package com.tools.web.interceptor.limiting;

import com.tools.common.object.Note;
import com.tools.common.thread.Timeunit;
import com.tools.web.interceptor.auth.AuthenticationManager;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * 使用 RedisTemplate 客户端操作 Redis 实现的限流拦截器
 * */
@Note("使用 RedisTemplate 客户端操作 Redis 实现的限流拦截器")
public final class RedisTemplateReqLimitInterceptor extends RequestLimitInterceptor {

    @Note("RedisTemplate 操作 Redis 的客户端")
    private final RedisTemplate<String, String> cache;

    public RedisTemplateReqLimitInterceptor(RedisTemplate<String, String> cache, RequestLimitSource source) {
        this(cache, source, null);
    }

    public RedisTemplateReqLimitInterceptor(RedisTemplate<String, String> cache, RequestLimitSource source,
                                            AuthenticationManager authenticationManager) {
        super(source, cache != null, "RedisTemplate 客户端实例为 null", authenticationManager);
        this.cache = cache;
    }

    @Override
    protected Timeunit protected_getImplSelfTimeunit() {
        return Timeunit.SECOND;
    }

    @Override
    protected Integer protected_getRequestedCount(String key) {
        String s = this.cache.opsForValue().get(key);
        return (s == null) ? null : Integer.parseInt(s);
    }

    @Override
    protected void protected_setRequestedCount(String key, int count, long expiration, Timeunit timeunit) {
        this.cache.opsForValue().set(key, Integer.toString(count),
                Timeunit.toSecond(expiration, timeunit), TimeUnit.SECONDS);
    }

    @Override
    protected long protected_getRemainder(String key) {
        Long expire = this.cache.getExpire(key);
        return (expire == null) ? -1 : expire;
    }

    @Override
    protected void protected_removeRequestCount(String key) {
        this.cache.delete(key);
    }
}
